home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / networking / mail / mailqueue372.lha / MailQueue / MailQueue.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-15  |  14.0 KB  |  533 lines

  1. /*
  2. Auto:        sc <file>
  3. Auto:        Protect <file> ADD p
  4. */
  5.  
  6.  
  7. /* $Revision Header built automatically *************** (do not edit) ************
  8. **
  9. ** © Copyright by GuntherSoft
  10. **
  11. ** File             : SnakeSYS:CPrgs/MailQueue/MailQueue.c
  12. ** Created on       : Freitag, 13.01.95 17:12:27
  13. ** Created by       : Kai Iske
  14. ** Current revision : V37.2
  15. **
  16. **
  17. ** Purpose
  18. ** -------
  19. **     Watches your SMTP spool directory for the number of
  20. **     messages queued.
  21. **
  22. ** Revision V37.2
  23. ** --------------
  24. ** created on Mittwoch, 15.02.95 13:32:37  by  Kai Iske.   LogMessage :
  25. **   - Added SendMail switch, which acts as a SENDMAIL compatible
  26. **     switch. SendMail creates two D.#? entries for one mail.
  27. **     The SendMail switch causes MailQueue to halve the number
  28. **     of files found, in order to show the number of mails
  29. **     (Requested by : <phil@curve.demon.co.uk>)
  30. **
  31. ** Revision V37.1
  32. ** --------------
  33. ** created on Sonntag, 22.01.95 03:25:27  by  Greg Patterson.   LogMessage :
  34. **  -*-  changed on Montag, 23.01.95 20:38:31  by  Kai Iske.   LogMessage :
  35. **   - Added new ONLYWB option, whichs causes the program
  36. **     to only open it`s window, on Workbench
  37. **  -*-  changed on Montag, 23.01.95 19:22:49  by  Kai Iske.   LogMessage :
  38. **   - MailQueue wasn`t really pure, as it used to set up LibBases
  39. **     as globals (well, technically wasn`t pure ;)). Changed.
  40. **     (Reported by : WShell users)
  41. **  -*-  changed on Sonntag, 22.01.95 23:37:04  by  Kai Iske.   LogMessage :
  42. **   - Whoops, wrong version string contained in executable ;)
  43. **  -*-  created on Sonntag, 22.01.95 03:25:27  by  Greg Patterson.   LogMessage :
  44. **   - Added ZEROCLOSE option to hide the Queue window when no messages are
  45. **     queued.
  46. **
  47. ** Revision V37.0
  48. ** --------------
  49. ** created on Freitag, 13.01.95 17:12:27  by  Kai Iske.   LogMessage :
  50. **     --- Initial release ---
  51. **
  52. *********************************************************************************/
  53. #define REVISION "37.2"
  54. #define REVDATE  "15.02.95"
  55. #define REVTIME  "13:32:37"
  56. #define AUTHOR   "Kai Iske"
  57. #define VERNUM   37
  58. #define REVNUM   2
  59.  
  60.  
  61.  
  62. #include    <stdlib.h>
  63. #include    <stdio.h>
  64. #include    <string.h>
  65. #include    <stdarg.h>
  66. #include    <exec/types.h>
  67. #include    <exec/memory.h>
  68. #include    <exec/execbase.h>
  69. #include    <proto/exec.h>
  70. #include    <proto/dos.h>
  71. #include    <proto/intuition.h>
  72. #include    <proto/netsupport.h>
  73. #include    <dos/dos.h>
  74. #include    <dos/dosextens.h>
  75. #include    <dos/notify.h>
  76. #include    <dos/exall.h>
  77. #include    <intuition/intuition.h>
  78.  
  79.  
  80.  
  81. /**********************************************************************/
  82. /*                           Version String                           */
  83. /**********************************************************************/
  84. static    const    char    Ver[]        = "$VER: MailQueue "REVISION" ("REVDATE")\0";
  85.  
  86.  
  87.  
  88.  
  89. /**********************************************************************/
  90. /*                              Template                              */
  91. /**********************************************************************/
  92. static    const    char    Template[]    = "WinX/N,WinY/N,OPENNOW/S,ZEROCLOSE/S,ONLYWB/S,SENDMAIL/S";
  93. enum{WINX_ARG, WINY_ARG, OPENNOW_ARG, ZEROCLOSE_ARG, ONLYWB_ARG, SENDMAIL_ARG, LAST_ARG};
  94.  
  95.  
  96.  
  97. /**********************************************************************/
  98. /*                        Our notify structure                        */
  99. /**********************************************************************/
  100. struct    NotifyNode
  101. {
  102.     struct    Node        Link;
  103.     struct    NotifyRequest    Notify;
  104.     char            Name[258];
  105. };
  106.  
  107.  
  108.  
  109.  
  110.  
  111. /**********************************************************************/
  112. /*                             Prototypes                             */
  113. /**********************************************************************/
  114. static    LONG    ScanDir(char *DirName, struct List *NotifyList, ULONG NotifySig, struct ExAllControl *EAC, struct ExAllData *EAB, struct DosLibrary *DOSBase);
  115. static    void    __stdargs SPrintF(STRPTR buffer, STRPTR formatString,...);
  116.  
  117.  
  118.  
  119.  
  120.  
  121. /**********************************************************************/
  122. /*                       This is the main stuff                       */
  123. /**********************************************************************/
  124. ULONG __saveds MailQueue(void)
  125. {
  126.     struct    ExecBase        *SysBase    = *((struct ExecBase **)0x4L);
  127.     struct    DosLibrary        *DOSBase;
  128.     struct    IntuitionBase        *IntuitionBase;
  129.     struct    NetSupportLibrary    *NetSupportBase;
  130.     struct    Process            *MyProc        = (struct Process *)SysBase->ThisTask;
  131.     struct    RDArgs            *RDArgs;
  132.     struct    ExAllControl        *EAC;
  133.     struct    ExAllData        *EAB;
  134.     LONG                NotifySig;
  135.     APTR                *Args;
  136.     ULONG                NotifyMask,
  137.                     MySig;
  138.     BOOL                Error        = TRUE;
  139.  
  140.  
  141.         // Ignore startup from WB
  142.  
  143.     if(!(MyProc->pr_CLI))
  144.     {
  145.         struct    Message *MyMsg;
  146.  
  147.         WaitPort(&MyProc->pr_MsgPort);
  148.         MyMsg = GetMsg(&MyProc->pr_MsgPort);
  149.         Disable();
  150.         ReplyMsg(MyMsg);
  151.         return(10);
  152.     }
  153.  
  154.         // Do the wild thing
  155.  
  156.     if((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)))
  157.     {
  158.         if((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)))
  159.         {
  160.             if((NetSupportBase = (struct NetSupportLibrary *)OpenLibrary("netsupport.library", 1)))
  161.             {
  162.                 if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  163.                 {
  164.                     if((EAB = AllocVec(sizeof(struct ExAllData) * 16, MEMF_CLEAR)))
  165.                     {
  166.                         if((Args = AllocVec(LAST_ARG * sizeof(ULONG), MEMF_CLEAR)))
  167.                         {
  168.                             char    *Entry;
  169.  
  170.                             Entry    = GetConfig(NULL, "SMTPSPOOLDIR", "SMTPSPOOLDIR", "");
  171.  
  172.                             if(Entry && strlen(Entry))
  173.                             {
  174.                                 if((RDArgs = ReadArgs((char *)Template, (LONG *)Args, NULL)))
  175.                                 {
  176.                                     if((NotifySig = AllocSignal(-1)) != -1)
  177.                                     {
  178.                                         struct    List        NotifyList;
  179.                                         struct    NotifyRequest    DirNotify;
  180.                                         struct    NotifyNode    *Notify;
  181.                                         struct    Window        *NotifyWindow    = NULL;
  182.                                         ULONG            NotifyWinSig    = 0,
  183.                                                     WinLeft        = 0,
  184.                                                     WinTop        = 0;
  185.                                         char            WinTitle[80];
  186.                                         BOOL            Initial        = TRUE,
  187.                                                     ZeroClose    = TRUE,
  188.                                                     OnlyWB        = FALSE,
  189.                                                     SendMail    = FALSE;
  190.  
  191.                                             // Get arguments
  192.  
  193.                                         if(Args[WINX_ARG])
  194.                                             WinLeft        = *((ULONG *)Args[WINX_ARG]);
  195.  
  196.                                         if(Args[WINY_ARG])
  197.                                             WinTop        = *((ULONG *)Args[WINY_ARG]);
  198.  
  199.                                         if(!Args[OPENNOW_ARG])
  200.                                             Initial        = FALSE;
  201.  
  202.                                         if(!Args[ZEROCLOSE_ARG])
  203.                                             ZeroClose    = FALSE;
  204.  
  205.                                         if(Args[ONLYWB_ARG])
  206.                                             OnlyWB        = TRUE;
  207.  
  208.                                         if(Args[SENDMAIL_ARG])
  209.                                             SendMail    = TRUE;
  210.  
  211.  
  212.                                             // Set up list of notification requests
  213.  
  214.                                         NewList(&NotifyList);
  215.  
  216.                                             // Init notification for Directory
  217.                                             // and cause initial notification
  218.  
  219.                                         DirNotify.nr_Name                = Entry;
  220.                                         DirNotify.nr_Flags                = NRF_SEND_SIGNAL|NRF_NOTIFY_INITIAL;
  221.                                         DirNotify.nr_stuff.nr_Signal.nr_Task        = MyProc;
  222.                                         DirNotify.nr_stuff.nr_Signal.nr_SignalNum    = NotifySig;
  223.  
  224.                                             // Do it
  225.  
  226.                                         if(StartNotify(&DirNotify))
  227.                                         {
  228.                                             Error        = FALSE;
  229.  
  230.                                                 // Get Mask for Notification Signal
  231.  
  232.                                             NotifyMask    = 1 << NotifySig;
  233.  
  234.                                             for(;;)
  235.                                             {
  236.                                                 MySig    = Wait(SIGBREAKF_CTRL_C|NotifyMask|NotifyWinSig);
  237.  
  238.                                                     // Quit now
  239.  
  240.                                                 if(MySig & SIGBREAKF_CTRL_C)
  241.                                                     break;
  242.  
  243.                                                     // Anything has changed within the dir
  244.  
  245.                                                 if(MySig & NotifyMask)
  246.                                                 {
  247.                                                     LONG            Number;
  248.  
  249.                                                         // Rescan directory and set up new
  250.                                                         // notifications for files within the dir
  251.                                                         // Create appropriate Window title
  252.  
  253.                                                     if((Number = ScanDir(Entry, &NotifyList, NotifySig, EAC, EAB, DOSBase)) != -1)
  254.                                                     {
  255.                                                         if(SendMail)
  256.                                                             Number    = Number >> 1;
  257.  
  258.                                                         if(ZeroClose && !Number && NotifyWindow)
  259.                                                         {
  260.                                                             CloseWindow(NotifyWindow);
  261.                                                             NotifyWindow    = NULL;
  262.                                                             NotifyWinSig    = 0;
  263.                                                         }
  264.                                                         else
  265.                                                             SPrintF(WinTitle, "%ld Message(s) queued", Number);
  266.                                                     }
  267.                                                     else
  268.                                                         strcpy(WinTitle, "Couldn`t get information");
  269.  
  270.                                                         // Update window?
  271.  
  272.                                                     if(NotifyWindow || Number > 0 || Initial)
  273.                                                     {
  274.                                                             // Window not opened yet?
  275.  
  276.                                                         if(!NotifyWindow)
  277.                                                         {
  278.                                                             struct    Screen    *WB    = LockPubScreen((OnlyWB ? "Workbench" : NULL));
  279.  
  280.                                                                 // Open window
  281.  
  282.                                                             if(WB)
  283.                                                             {
  284.                                                                 if((NotifyWindow = OpenWindowTags(NULL,
  285.                                                                     WA_Left,    WinLeft,
  286.                                                                     WA_Top,        WinTop,
  287.                                                                     WA_Width,    (WB->RastPort.TxWidth * 40),
  288.                                                                     WA_Height,    (WB->RastPort.TxHeight + 3),
  289.                                                                     WA_Flags,    WFLG_DRAGBAR|WFLG_CLOSEGADGET|WFLG_DEPTHGADGET,
  290.                                                                     WA_IDCMP,    IDCMP_CHANGEWINDOW|IDCMP_CLOSEWINDOW,
  291.                                                                     WA_PubScreen,    WB,
  292.                                                                     WA_Title,    WinTitle,
  293.                                                                 TAG_DONE)))
  294.                                                                     NotifyWinSig    = 1 << NotifyWindow->UserPort->mp_SigBit;
  295.  
  296.                                                                 UnlockPubScreen(NULL, WB);
  297.                                                             }
  298.                                                         }
  299.                                                         else
  300.                                                             SetWindowTitles(NotifyWindow, WinTitle, (char *)~0);
  301.  
  302.                                                         Initial = FALSE;
  303.                                                     }
  304.                                                 }
  305.  
  306.                                                     // Signal from window?
  307.  
  308.                                                 if(MySig & NotifyWinSig)
  309.                                                 {
  310.                                                     struct    IntuiMessage    *Msg;
  311.                                                     BOOL            Close    = FALSE;
  312.  
  313.                                                     while((Msg = (struct IntuiMessage *)GetMsg(NotifyWindow->UserPort)))
  314.                                                     {
  315.                                                         if(Msg->Class == IDCMP_CLOSEWINDOW)
  316.                                                             Close    = TRUE;
  317.                                                         else if(Msg->Class == IDCMP_CHANGEWINDOW)
  318.                                                         {
  319.                                                             WinLeft = NotifyWindow->LeftEdge;
  320.                                                             WinTop    = NotifyWindow->TopEdge;
  321.                                                         }
  322.  
  323.                                                         ReplyMsg((struct Message *)Msg);
  324.                                                     }
  325.  
  326.                                                     if(Close)
  327.                                                     {
  328.                                                         CloseWindow(NotifyWindow);
  329.                                                         NotifyWindow    = NULL;
  330.                                                         NotifyWinSig    = 0;
  331.                                                     }
  332.                                                 }
  333.                                             }
  334.  
  335.                                                 // Close window
  336.  
  337.                                             if(NotifyWindow)
  338.                                                 CloseWindow(NotifyWindow);
  339.  
  340.                                                 // Kill Notifications
  341.  
  342.                                             while((Notify = (struct NotifyNode *)RemHead(&NotifyList)))
  343.                                             {
  344.                                                 EndNotify(&Notify->Notify);
  345.                                                 FreeVec(Notify);
  346.                                             }
  347.  
  348.                                                 // End Dir Notification
  349.  
  350.                                             EndNotify(&DirNotify);
  351.                                         }
  352.                                         else
  353.                                             FPuts(Output(), "MailQueue : Couldn`t launch Notification\n");
  354.  
  355.                                         FreeSignal(NotifySig);
  356.                                     }
  357.                                     else
  358.                                         FPuts(Output(), "MailQueue : Couldn`t allocate Signal\n");
  359.  
  360.                                     FreeArgs(RDArgs);
  361.                                 }
  362.                                 else
  363.                                     PrintFault(IoErr(), "MailQueue ");
  364.                             }
  365.                             else
  366.                                 FPuts(Output(), "MailQueue : SMTPSPOOLDIR settings not found\n");
  367.  
  368.                             FreeVec(Args);
  369.                         }
  370.                         else
  371.                             PrintFault(ERROR_NO_FREE_STORE, "MailQueue ");
  372.  
  373.                         FreeVec(EAB);
  374.                     }
  375.                     else
  376.                         PrintFault(ERROR_NO_FREE_STORE, "MailQueue ");
  377.  
  378.                     FreeDosObject(DOS_EXALLCONTROL, EAC);
  379.                 }
  380.                 else
  381.                     PrintFault(ERROR_NO_FREE_STORE, "MailQueue ");
  382.  
  383.                 CloseLibrary((struct Library *)NetSupportBase);
  384.             }
  385.             else
  386.                 FPuts(Output(), "MailQueue : Couldn`t open netsupport.library\n");
  387.  
  388.             CloseLibrary((struct Library *)IntuitionBase);
  389.         }
  390.         else
  391.             FPuts(Output(), "MailQueue : Couldn`t open intuition.library\n");
  392.  
  393.         CloseLibrary((struct Library *)DOSBase);
  394.     }
  395.  
  396.     if(Error)
  397.         return(10);
  398.     else
  399.         return(0);
  400. }
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409. /**********************************************************************/
  410. /*            Scan the directory for the "D.#?" files                 */
  411. /**********************************************************************/
  412. static LONG ScanDir(char *DirName, struct List *NotifyList, ULONG NotifySig, struct ExAllControl *EAC, struct ExAllData *EAB, struct DosLibrary *DOSBase)
  413. {
  414.     struct    NotifyNode    *Notify;
  415.     struct    ExAllData    *EAD;
  416.     BPTR            DirLock;
  417.     char            Pattern[32];
  418.     LONG            Number        = -1;
  419.     BOOL            Scanning;
  420.  
  421.  
  422.         // First stop all pending notifications
  423.  
  424.     while((Notify = (struct NotifyNode *)RemHead(NotifyList)))
  425.     {
  426.         EndNotify(&Notify->Notify);
  427.         FreeVec(Notify);
  428.     }
  429.  
  430.         // Create pattern for files (Message files start with "D.")
  431.  
  432.     if(ParsePatternNoCase("D.#?", Pattern, 32) != -1)
  433.     {
  434.             // Scan directory
  435.  
  436.         if((DirLock = Lock(DirName, ACCESS_READ)))
  437.         {
  438.             EAC->eac_LastKey    = 0;
  439.             EAC->eac_MatchString    = Pattern;
  440.             EAC->eac_MatchFunc    = 0;
  441.  
  442.             Number        = 0;
  443.  
  444.             do
  445.             {
  446.                 Scanning    = ExAll(DirLock, EAB, (16 * sizeof(struct ExAllControl)), ED_NAME, EAC);
  447.  
  448.                 if(!Scanning && (IoErr() != ERROR_NO_MORE_ENTRIES))
  449.                     Number    = -1;
  450.  
  451.                 if(EAC->eac_Entries == 0)
  452.                     Scanning    = FALSE;
  453.                 else if(Number != -1)
  454.                 {
  455.                     EAD    = EAB;
  456.  
  457.                     do
  458.                     {
  459.                             // Create new notification for file found
  460.  
  461.                         if((Notify = AllocVec(sizeof(struct NotifyNode), MEMF_CLEAR)))
  462.                         {
  463.                             Number++;
  464.  
  465.                                 // Create filename with path
  466.  
  467.                             NameFromLock(DirLock, Notify->Name, 256);
  468.                             AddPart(Notify->Name, EAD->ed_Name, 256);
  469.  
  470.                                 // Set up notification on file
  471.  
  472.                             Notify->Notify.nr_Name                = Notify->Name;
  473.                             Notify->Notify.nr_Flags                = NRF_SEND_SIGNAL;
  474.                             Notify->Notify.nr_stuff.nr_Signal.nr_Task    = FindTask(NULL);
  475.                             Notify->Notify.nr_stuff.nr_Signal.nr_SignalNum    = NotifySig;
  476.  
  477.                                 // Start notification
  478.  
  479.                             if(!StartNotify(&Notify->Notify))
  480.                             {
  481.                                     // Error -> Abort and free memory of node
  482.  
  483.                                 Number    = -1;
  484.                                 FreeVec(Notify);
  485.                                 break;
  486.                             }
  487.                             else
  488.                             {
  489.                                     // Add node to list
  490.  
  491.                                 AddTail(NotifyList, (struct Node *)Notify);
  492.                             }
  493.                         }
  494.                         else
  495.                             Number    = -1;
  496.  
  497.                         EAD    = EAD->ed_Next;
  498.                     } while(EAD && Number != -1);
  499.                 }
  500.             } while(Scanning && Number != -1);
  501.  
  502.             UnLock(DirLock);
  503.         }
  504.     }
  505.  
  506.         // Error?!?! Kill requests
  507.  
  508.     if(Number == -1)
  509.     {
  510.         while((Notify = (struct NotifyNode *)RemHead(NotifyList)))
  511.         {
  512.             EndNotify(&Notify->Notify);
  513.             FreeVec(Notify);
  514.         }
  515.     }
  516.  
  517.     return(Number);
  518. }
  519.  
  520.  
  521.  
  522.  
  523. /**********************************************************************/
  524. /*               My special sprintf                  */
  525. /**********************************************************************/
  526. static void __stdargs SPrintF(STRPTR buffer, STRPTR formatString,...)
  527. {
  528.     va_list varArgs;
  529.     va_start(varArgs,formatString);
  530.     RawDoFmt(formatString,varArgs,(void (*)())(void (*))"\x16\xC0\x4E\x75",buffer);
  531.     va_end(varArgs);
  532. }
  533.